package com.baizhi.config.log;

import com.baizhi.entity.CmfzLog;
import com.baizhi.mapper.CmfzLogMapper;
import com.baizhi.util.IPKit;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Slf4j
@Configuration
@Aspect
public class LogAspect {
    @Autowired
    private CmfzLogMapper cmfzLogMapper;
    /**
     * 1 获取日志数据
     *
     * 2 日志数据添加数据库
     *
     * 切方法和切注解
     *
     * 只能切注解 因为不是所有的方法都有日志注解
     *
     * 凡是添加了日志注解的方法才会被 aop
     */
    @After("@annotation(com.baizhi.config.log.LogAnnotation)")
    public void logAfter(JoinPoint joinPoint){
        log.info("开始执行日志增强");
        /**
         * 1 获取日志数据
         */
        CmfzLog cmfzLog = new CmfzLog();
//        1.时间
        cmfzLog.setLogDate(new Date());
//        2.ip 通过请求可以获取到 Request（当前线程的Request）
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //        通过工具类
        String ip = IPKit.getIpAddrByRequest(request);
        cmfzLog.setLogIp(ip);
//       3. 管理员的名字
        String username = (String) request.getSession().getAttribute("username");
        if(username != null){
            cmfzLog.setUsername(username);
        }else{
            cmfzLog.setUsername("root");
        }
        //        操作内容 和 类型
        /**
         * 执行的方法不同 获取到内容和类型不同
         *
         * 自定义注解的方式  获取目标方法注解的值  因为注解的值可以写的不一样 所以每一次拿到数据也不一样
         *
         * 通过切入点对象可以获取目标方法的所有内容 方法本身  方法的注解 方法所在的对象 等
         */
//        1.获取方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        2.获取方法对象
        Method method = signature.getMethod();
//        3.获取方法上的注解
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
//        4.获取注解的值
        cmfzLog.setLogContent(annotation.content());
        cmfzLog.setLogType(annotation.type());
        /**
         * 2 日志数据添加数据库
         */
        cmfzLogMapper.insert(cmfzLog);
        log.info("日志增强结束");
    }
}
